#include "usart.h"


static const char *TAG = "UART_ISR";
static QueueHandle_t uart_queue;
// 全局变量
// static QueueHandle_t rfid_cmd_queue;
// static SemaphoreHandle_t uart_mutex;
#define RXBUFFSIZE      1024
static uint8_t RxBuff[RXBUFFSIZE];
static uint16_t RxCnt = 0;
typedef enum {
    CHECK_OK = 0,
    ERR_START_BYTE,
    ERR_END_BYTE,
    ERR_LENGTH_MISMATCH,
    ERR_CHECKSUM
} CheckResult;



static void RxBuffClear()
{
    memset(RxBuff,0,sizeof(RxBuff));
    RxCnt = 0;
}


CheckResult verify_rfid_frame(const uint8_t *data, int len) {
    // 基础结构校验
    if (len < 6) return ERR_LENGTH_MISMATCH; // 最小帧长度=起始1+地址1+命令1+长度1+数据1+校验1+结束1=6
    
    // 帧头帧尾校验
    if (data[0] != 0x20) return ERR_START_BYTE;
    if (data[len-1] != 0x03) return ERR_END_BYTE;

    // 获取数据长度字段（第4字节）
    uint8_t data_length = data[3];
    
    // 校验总长度是否符合：1(start) + 1(addr) + 1(cmd) + 1(len) + data_length + 1(checksum) + 1(end)
    if (len != (5 + data_length + 1)) { 
        return ERR_LENGTH_MISMATCH;
    }

    // 计算校验和范围：从地址字节(第2字节)到数据区最后一个字节
    uint8_t calculated_checksum = 0;
    for (int i = 1; i < 4 + data_length; i++) { // 从地址字节到数据区结束
        calculated_checksum ^= data[i];
    }
    calculated_checksum = ~calculated_checksum;

    // 获取帧中的校验字节（倒数第二字节）
    uint8_t received_checksum = data[len - 2];
    // ESP_LOGW(TAG, "calculated_checksum = %d  received_checksum = %d",calculated_checksum,received_checksum);
    return (calculated_checksum == received_checksum) ? CHECK_OK : ERR_CHECKSUM;
}


static uint8_t Analysis_Rfid_Data_Cmd(uint8_t *buff,uint8_t len,uint8_t *recv_buff,uint8_t *recv_len,uint8_t *cmd)
{
    ESP_LOGI(TAG, "Received %d bytes:", len);
    // 打印十六进制和ASCII
    // printf("HEX: "); 
    for (int i = 0; i < len; i++) printf("%02X ", buff[i]);
    printf("\r\n"); 
    if(len < 6){return 0;}
    // int i = 0;
    uint8_t data_len = 6 + buff[3];
    if(buff[0] == 0x20 && data_len <= len)
    {
        CheckResult res = verify_rfid_frame(buff,len);
        if(res == CHECK_OK)
        {
            memcpy(recv_buff,&buff[4],buff[3]);
            *recv_len = buff[3];
            // ESP_LOGW(TAG, "数据校验成功");    
            *cmd = buff[2];
            return 1;
        }
        else{
            ESP_LOGW(TAG, "数据校验错误res = %d",res);
            ESP_LOGI(TAG, "Received %d bytes:", len);
            // 打印十六进制和ASCII
            printf("HEX: "); 
            for (int i = 0; i < len; i++) printf("%02X ", buff[i]);
            printf("\r\n"); 
        }
    }
    return 0;
}

static uint8_t Analysis_Rfid_Data(uint8_t *buff,uint8_t len,uint8_t *recv_buff,uint8_t *recv_len,uint8_t cmd)
{
    // ESP_LOGI(TAG, "Received %d bytes:", len);
    // 打印十六进制和ASCII
    // printf("HEX: "); 
    // for (int i = 0; i < len; i++) printf("%02X ", buff[i]);
    // printf("\r\n"); 
    if(len < 6){return 0;}
    // int i = 0;
    uint8_t data_len = 6 + buff[3];
    if(buff[0] == 0x20 && data_len <= len)
    {
        CheckResult res = verify_rfid_frame(buff,len);
        if(res == CHECK_OK)
        {
            if(cmd == buff[2]){
                memcpy(recv_buff,&buff[4],buff[3]);
                *recv_len = buff[3];
                // ESP_LOGW(TAG, "数据校验成功");    
                return 1;
            }
            // else if()
            // {

            // }
        }
        else{
            ESP_LOGW(TAG, "数据校验错误res = %d",res);
            ESP_LOGI(TAG, "Received %d bytes:", len);
            // 打印十六进制和ASCII
            printf("HEX: "); 
            for (int i = 0; i < len; i++) printf("%02X ", buff[i]);
            printf("\r\n"); 
        }
    }
    return 0;
}


static void uart_event_task(void *pvParameters) {
    QueueHandle_t uart_queue = (QueueHandle_t)pvParameters;
    uart_event_t event;
    uint8_t *data = malloc(BUF_SIZE);
    while (1) {
        // 等待UART事件（阻塞式）
        if (xQueueReceive(uart_queue, &event, portMAX_DELAY)) {
            switch (event.type) {
                case UART_DATA:  // 数据到达事件
                    // 读取数据
                    int len = uart_read_bytes(UART_NUM, data, BUF_SIZE, pdMS_TO_TICKS(100));
                    if (len > 0) {
                        // Analysis_Rfid_Data(data,len);
                        if(RxCnt + len >= RXBUFFSIZE){
                            RxCnt = 0;
                        }
                        // mempcpy(RxBuff,data,len);
                        memcpy(RxBuff + RxCnt,data,len);
                        RxCnt += len;
                        // ESP_LOGW(TAG, "copycnt = %d", RxCnt);
                        
                        // memcpy()
                    }
                    break;

                case UART_FIFO_OVF:  // FIFO溢出
                    ESP_LOGE(TAG, "FIFO Overflow!");
                    uart_flush(UART_NUM);
                    break;
                case UART_BREAK:
                    break;
                default:
                    ESP_LOGW(TAG, "Unhandled UART event: %d", event.type);
                    break;
            }
        }
    }
    free(data);
    vTaskDelete(NULL);
}

static uint8_t SendCmdData(uint8_t *send_buff,uint8_t send_len,uint8_t cmd,uint8_t *recv_buff,uint8_t recv_len,uint16_t over_time)
{
    uint16_t cnt = 0, once_time = 100;
    // ESP_LOG(TAG,"send:%s")
    RxBuffClear();
    Usart_Send(send_buff,send_len);
    while(cnt*once_time < over_time)
    {
        if(Analysis_Rfid_Data(RxBuff,RxCnt,recv_buff,&recv_len,cmd)){
            return 1;
        }
        cnt++;
        vTaskDelay(once_time);
    }
    return 0;
}



static void Rfid_Logic_Thread(void *pargem)
{
    uint8_t send_buff[48];
    uint8_t send_cnt = 0;
    uint8_t recv_buff[48];
    uint8_t recv_cnt = 0;
    uint8_t cmd = 0;
    uint8_t step = 0;
    while(1)
    {
        step++;
        if(gs_rfid.rfid_drive_flag == 0){
            memset(send_buff,0,sizeof(send_buff));
            send_buff[send_cnt++] = 0x20;send_buff[send_cnt++] = 0x00;send_buff[send_cnt++] = 0x2D;send_buff[send_cnt++] = 0x00;send_buff[send_cnt++] = 0xD2;send_buff[send_cnt++] = 0x03;
            // Usart_Send(send_buff,send_cnt);
            if(SendCmdData(send_buff,send_cnt,0x2D,recv_buff,recv_cnt,1000)){
                gs_rfid.rfid_drive_flag = 1;
            }
        }
        else if(RxCnt > 0)
        {
            if(Analysis_Rfid_Data_Cmd(RxBuff,RxCnt,recv_buff,&recv_cnt,&cmd))
            {
                if(cmd == 0x00)
                {
                    if(recv_buff[0] == 0x02){
                        ESP_LOGW(TAG,"卡片离开");    
                        memset(gs_rfid.card_id_str,0,sizeof(gs_rfid.card_id_str));
                        gs_rfid.car_state = CAR_LEAVE;
                        step = 0;
                    }
                    else if (recv_buff[0] == 0x04) {
                        ESP_LOGW(TAG,"读卡成功 卡号:");
                        int offset = 0;
                        for (int i = 3; i < recv_cnt; i++) {
                            offset += snprintf((char *)gs_rfid.card_id_str + offset, 
                                               sizeof(gs_rfid.card_id_str) - offset, 
                                               "%02X", 
                                               (unsigned char)recv_buff[i]);
                        }
                        printf("\r\n");
                        ESP_LOGW(TAG, "卡号: %s", gs_rfid.card_id_str);
                        gs_rfid.car_state = CAR_READ_SUCCESS;
                        step = 12;
                    }
                }
                else if(cmd == 0x22)
                {
                    if(recv_buff[0] == 0x00)
                    {
                        if(gs_rfid.car_state == CAR_READ_SUCCESS)
                        {
                            ESP_LOGW(TAG,"读卡块 65 成功 byte = %d :",recv_cnt);
                            gs_rfid.car_state = CAR_READ_PIECED;
                            for (int i = 1; i < recv_cnt; i++) printf("%02X ", recv_buff[i]);
                            memcpy(gs_rfid.bolck_data,&recv_buff[1],recv_cnt - 1);
                            gs_rfid.bolck_flag = true;
                            printf("\r\n");   
                        }
                        else{
                            ESP_LOGW(TAG,"读卡块 %d 成功 byte = %d :",gs_rfid.bolck_addr,recv_cnt);
                            gs_rfid.car_state = CAR_READ_BLAKE_SUCCESS;
                            for (int i = 1; i < recv_cnt; i++) printf("%02X ", recv_buff[i]);
                            memcpy(gs_rfid.read_date,&recv_buff[1],recv_cnt - 1);
                            gs_rfid.read_cnt = 16;
                            printf("\r\n");   
                        }

                    }
                    else{
                        if(gs_rfid.car_state == CAR_READ_BLAKE_DATA){
                            gs_rfid.car_state = CAR_READ_BLAKE_FAIL;
                        }
                        step = 12;
                    }
                }
                else if(cmd == 0x23)
                {
                    if(recv_buff[0] == 0x00)
                    {
                        ESP_LOGW(TAG,"写卡块 %d 成功 byte = %d :",gs_rfid.bolck_addr,recv_cnt);
                        gs_rfid.car_state = CAR_WRITE_BLAKE_SUCCESS;
                    }
                    else{
                        gs_rfid.car_state = CAR_WRITE_BLAKE_FAIL;
                        ESP_LOGE(TAG,"写卡块 %d 失败 byte = %d :",gs_rfid.bolck_addr,recv_cnt);
                    }
                }
            }
            RxBuffClear();
        }
        else if(gs_rfid.car_state == CAR_WRITE_BLAKE_DATA && step > 10)
        {
            uint8_t temp_buff[32];
            uint8_t temp_cnt = 0;
            temp_buff[temp_cnt++] = 0x20;temp_buff[temp_cnt++] = 0x00;temp_buff[temp_cnt++] = 0x23;temp_buff[temp_cnt++] = 0x18;
            temp_buff[temp_cnt++] = 0x00;
            temp_buff[temp_cnt++] = 0xFF;temp_buff[temp_cnt++] = 0xff;temp_buff[temp_cnt++] = 0xff;temp_buff[temp_cnt++] = 0xFF;temp_buff[temp_cnt++] = 0xff;temp_buff[temp_cnt++] = 0xff;  //密码
            temp_buff[temp_cnt++] = gs_rfid.bolck_addr;
            for(uint8_t i = 0; i < gs_rfid.write_cnt;i++){ temp_buff[temp_cnt++] = gs_rfid.write_data[i];}
            uint8_t crc = 0;
            for(uint8_t i=1;i<temp_cnt;i++){crc ^= temp_buff[i];}
            temp_buff[temp_cnt++] = ~crc; temp_buff[temp_cnt++] = 0x03;
            RxBuffClear();
            Usart_Send(temp_buff,temp_cnt);
            step = 0;
            // if(SendCmdData(temp_buff,temp_cnt,0x23,recv_buff,recv_cnt,1000)){
            //     if(recv_buff[0] == 1){
            //         gs_rfid.car_state = CAR_SUCCESS;
            //         ESP_LOGI(TAG,"写操作成功");
            //         continue;
            //     }
            // }
            // gs_rfid.car_state = CAR_FAIL;
            // ESP_LOGI(TAG,"写操作失败");
            // continue;
        }
        else if(gs_rfid.car_state == CAR_READ_BLAKE_DATA && step > 10)
        {
            uint8_t temp_buff[32];
            uint8_t temp_cnt = 0;
            temp_buff[temp_cnt++] = 0x20;temp_buff[temp_cnt++] = 0x00;temp_buff[temp_cnt++] = 0x22;temp_buff[temp_cnt++] = 0x08;
            temp_buff[temp_cnt++] = 0x00;
            temp_buff[temp_cnt++] = 0xFF;temp_buff[temp_cnt++] = 0xff;temp_buff[temp_cnt++] = 0xff;temp_buff[temp_cnt++] = 0xFF;temp_buff[temp_cnt++] = 0xff;temp_buff[temp_cnt++] = 0xff;  //密码
            temp_buff[temp_cnt++] = gs_rfid.bolck_addr;
            uint8_t crc = 0;
            for(uint8_t i=1;i<temp_cnt;i++){crc ^= temp_buff[i];}
            temp_buff[temp_cnt++] = ~crc; temp_buff[temp_cnt++] = 0x03;
            RxBuffClear();
            Usart_Send(temp_buff,temp_cnt);
            step = 0;
        }
        else if(gs_rfid.car_state == CAR_READ_SUCCESS && step > 10)
        {
            // 立马读取 65 块的数据
            memset(send_buff,0,sizeof(send_buff));
            send_buff[send_cnt++] = 0x20;send_buff[send_cnt++] = 0x00;send_buff[send_cnt++] = 0x22;send_buff[send_cnt++] = 0x08;send_buff[send_cnt++] = 0x00;
            send_buff[send_cnt++] = 0xFF;send_buff[send_cnt++] = 0xFF;send_buff[send_cnt++] = 0xFF;send_buff[send_cnt++] = 0xFF;send_buff[send_cnt++] = 0xFF;send_buff[send_cnt++] = 0xFF;
            send_buff[send_cnt++] = 0x41;
            send_buff[send_cnt++] = 0x94;
            send_buff[send_cnt++] = 0x03;
            RxBuffClear();
            Usart_Send(send_buff,send_cnt);
            ESP_LOGW(TAG,"发送读取块数据");
            step = 0;
        }
        vTaskDelay(50);
        // ESP_LOGW(TAG,"car_state:%d gs_rfid.rfid_drive_flag:%d",gs_rfid.car_state,gs_rfid.rfid_drive_flag);
    }
    // ESP_LOGE(TAG,"=============================================== fail");
}


void Usart_Init(void) {

    // 创建RFID队列和互斥锁
    // rfid_cmd_queue = xQueueCreate(5, (char*));
    // uart_mutex = xSemaphoreCreateMutex();
    uart_config_t uart_config = {
        .baud_rate = BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT
    };

    
    ESP_ERROR_CHECK(uart_driver_install(UART_NUM, BUF_SIZE, BUF_SIZE, EVENT_QUEUE_LEN, &uart_queue, 0));
    ESP_ERROR_CHECK(uart_param_config(UART_NUM, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(UART_NUM, TX_PIN, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));

    xTaskCreate(uart_event_task, "uart_event_task", 4096, (void*)uart_queue, configMAX_PRIORITIES-1, NULL);
    xTaskCreate(Rfid_Logic_Thread, "Rfid_Logic_Thread", 4096 * 2 , (void*)uart_queue, configMAX_PRIORITIES-1, NULL);
    ESP_LOGI(TAG, "UART2 initialized (TX=GPIO%d, RX=GPIO%d)", TX_PIN, RX_PIN);
}



void Usart_Send(const uint8_t *data, size_t len) {
    if (data == NULL || len == 0) {
        ESP_LOGE(TAG, "Invalid send parameters");
        return;
    }
    int sent = uart_write_bytes(UART_NUM, data, len);
    if (sent < 0) {
        ESP_LOGE(TAG, "UART send error");
    } else if (sent != len) {
        ESP_LOGW(TAG, "Partial send: %d/%d bytes", sent, (int)len);
    }
    else{
        ESP_LOGW(TAG, "成功发送");
    }
    
}



